package com.example.adminservice.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.adminservice.entity.Admin;
import com.example.adminservice.entity.BookAudit;
import com.example.adminservice.entity.ChapterAudit;
import com.example.adminservice.mapper.AdminMapper;
import com.example.adminservice.service.AdminService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.adminservice.service.BookAuditService;
import com.example.adminservice.service.ChapterAuditService;
import com.example.commom.enums.StatusCodeEnum;
import com.example.commom.global.KafkaConstants;
import com.example.commom.page.PageInfo;
import com.example.commom.page.PageVO;
import com.example.commom.redis.RedisUtils;
import com.example.commom.utils.JwtUtils;
import com.example.commom.utils.KafkaUtils;
import com.example.feign.result.AjaxResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 软工2104-李家强-2100770248
 * @since 2023-09-28
 */
@Slf4j
@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements AdminService {

    @Autowired
    private KafkaUtils kafkaUtils;

    @Autowired
    private BookAuditService bookAuditService;

    @Autowired
    private ChapterAuditService chapterAuditService;

    /**
     * 通过用户名, 查询用户信息
     * @param username 用户名
     * @return Admin 实体类
     */
    @Override
    public Admin getUserByName(String username) {

        LambdaQueryWrapper<Admin> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Admin::getUsername, username);

        return getOne(queryWrapper);
    }

    /**
     *  登录操作的业务逻辑
     * @param admin 管理员对象
     * @return Map结果集
     */
    @Override
    public HashMap<String, Object> successLogin(Admin admin) {
        // 密码正确, 生成 token
        String token = JwtUtils.generateToken(admin.getAdminId(),admin.getUsername(), admin.getType());

        // 向 kafka 推送消息将 token 存储到 redis 中.
        kafkaUtils.sendKafkaMessageWithRetry(KafkaConstants.KAFKA_ADMIN_LOGIN_STATUS_TOPIC,
                KafkaConstants.KAFKA_ADMIN_LOGIN_STATUS_TOPIC,
                (RedisUtils.getTokenRedisKey(admin.getType(), admin.getAdminId()) + ":true")
                        .getBytes(StandardCharsets.UTF_8));

        HashMap<String, Object> result = new HashMap<>();
        result.put("token", token);
        result.put("name", admin.getUsername());
        result.put("userId", admin.getAdminId());
        result.put("photo", admin.getPhoto());
        result.put("type", admin.getType());

        return result;
    }


    /**
     *  退出登录
     */
    @Override
    public AjaxResult exit(String token) {
        if (!StringUtils.hasLength(token)) {
            return AjaxResult.fail(StatusCodeEnum.Redirect.getCode(), StatusCodeEnum.Redirect.getMsg());
        }

        // 拿到登录用户的id和type
        String id = JwtUtils.getUserIdByToken(token);
        if (!StringUtils.hasLength(id)) {
            return AjaxResult.fail(StatusCodeEnum.Redirect.getCode(), StatusCodeEnum.Redirect.getMsg());
        }

        Admin adminInfo = getById(id);
        if (adminInfo == null || !"2".equals(adminInfo.getType()+"")) {
            return AjaxResult.fail(StatusCodeEnum.UNAUTHORIZED.getCode(), StatusCodeEnum.UNAUTHORIZED.getMsg());
        }


        // 向 kafka 推送消息, 删除 redis 中的 token
        kafkaUtils.sendKafkaMessageWithRetry(KafkaConstants.KAFKA_LOGIN_STATUS_TOPIC, KafkaConstants.KAFKA_LOGIN_STATUS_TOPIC,
                (RedisUtils.getTokenRedisKey(adminInfo.getType(), Long.parseLong(id)) + ":false")
                        .getBytes(StandardCharsets.UTF_8));

        return AjaxResult.success(StatusCodeEnum.OK.getCode(), StatusCodeEnum.OK.getMsg());
    }



    /**
     *  管理员审核书籍
     *  status: true-> 通过, false->不通过
     */
    @Override
    public AjaxResult approveBook(BookAudit bookAudit) {

        // 先插入审核表
        boolean save = bookAuditService.save(bookAudit);
        if (save) {
            // 发送消息
            kafkaUtils.sendKafkaMessageWithRetry(KafkaConstants.KAFKA_CHECK_BOOK_TOPIC, KafkaConstants.KAFKA_CHECK_BOOK_TOPIC,
                    (bookAudit.getBookId() + ":" + bookAudit.getStatus()).getBytes(StandardCharsets.UTF_8));

            return AjaxResult.success(StatusCodeEnum.OK.getMsg());

        } else {
            return AjaxResult.fail(StatusCodeEnum.FAILED.getMsg());
        }
    }


    /**
     *  审核章节
     */
    @Override
    public AjaxResult approveChapter(ChapterAudit chapterAudit) {

        // 插入审核表
        boolean save = chapterAuditService.save(chapterAudit);
        if (save) {

            // 向 kafka 推送消息
            kafkaUtils.sendKafkaMessageWithRetry(KafkaConstants.KAFKA_CHECK_CHAPTER_TOPIC, KafkaConstants.KAFKA_CHECK_CHAPTER_TOPIC,
                    (chapterAudit.getChapterId() + ":" + chapterAudit.getStatus()).getBytes(StandardCharsets.UTF_8));

            return AjaxResult.success(StatusCodeEnum.OK.getMsg());

        } else {
            return AjaxResult.fail(StatusCodeEnum.FAILED.getMsg());
        }
    }

    /**
     *  获取书籍审核历史记录
     */
    @Override
    public AjaxResult getBookHistory(String token, PageInfo pageInfo) {
        // 1. 权限校验

        String adminTokenId = JwtUtils.getUserIdByToken(token);
        if (adminTokenId == null ) {
            return AjaxResult.fail(StatusCodeEnum.UNAUTHORIZED.getCode(), StatusCodeEnum.UNAUTHORIZED.getMsg());
        }

        Admin admin = getById(Long.parseLong(adminTokenId));

        if (admin == null || !admin.getIsAvailable()) {
            return AjaxResult.fail(StatusCodeEnum.UNAUTHORIZED.getCode(), StatusCodeEnum.UNAUTHORIZED.getMsg());
        }


        // 2. 分页查询
        if (pageInfo.getPageNum() <= 0) {
            pageInfo.setPageNum(1);
        }

        if (pageInfo.getPageSize() <= 0) {
            pageInfo.setPageSize(20);
        }

        LambdaQueryWrapper<BookAudit> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(BookAudit::getAdminId, Long.parseLong(adminTokenId))
                .orderByDesc(BookAudit::getAuditDate);

        Page<BookAudit> page = bookAuditService.page(
                new Page<>(pageInfo.getPageNum(), pageInfo.getPageSize()),
                lambdaQueryWrapper
        );

        return AjaxResult.success(new PageVO<>(page));
    }

    /**
     *  获取章节审核历史记录
     */
    @Override
    public AjaxResult getChapterHistory(String token, PageInfo pageInfo) {
        // 1. 权限校验
        // 获取登录用户的 id
        String adminId = JwtUtils.getUserIdByToken(token);
        if (adminId == null ) {
            return AjaxResult.fail(StatusCodeEnum.UNAUTHORIZED.getCode(), StatusCodeEnum.UNAUTHORIZED.getMsg());
        }

        Admin admin = getById(Long.parseLong(adminId));

        if (admin == null || !admin.getIsAvailable()) {
            return AjaxResult.fail(StatusCodeEnum.UNAUTHORIZED.getCode(), StatusCodeEnum.UNAUTHORIZED.getMsg());
        }

        // 2. 分页查询
        if (pageInfo.getPageNum() <= 0) {
            pageInfo.setPageNum(1);
        }

        if (pageInfo.getPageSize() <= 0) {
            pageInfo.setPageSize(20);
        }

        LambdaQueryWrapper<ChapterAudit> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ChapterAudit::getAdminId, Long.parseLong(adminId))
                .orderByDesc(ChapterAudit::getAuditDate);

        Page<ChapterAudit> page = chapterAuditService.page(
                new Page<>(pageInfo.getPageNum(), pageInfo.getPageSize()),
                lambdaQueryWrapper
        );

        return AjaxResult.success(new PageVO<>(page));
    }

}

